/*
 * =====================================================================================
 *
 *       Filename:  graph.cpp
 *
 *    Description:  graph reading module
 *
 *        Version:  1.0
 *        Created:  08/11/2009 02:45:44 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Zhao Zhao
 *        Company:  ndssl
 *
 * =====================================================================================
 */

#include "utils.hpp"
#include "graph.h"
#include <iostream>
#include <fstream>

using namespace std;

Graph::Graph(void)
{
	graph = NULL;
	graphSize = 0;
	degree = NULL;

	directionOpt = false;
	weightOpt	= false;
}

Graph::~Graph(void)
{
}

void Graph::ReadGraph(const char* fPath)
{
	ifstream ifp(fPath);
	if(!ifp.is_open()) 
	{
		cout<<"Can not open "<<fPath<<endl;
		exit(1);
	}
	cout<<"Reading graph file: "<<fPath<<" ... "<<endl;
	cout.flush();
	
	VertexID count = 0;	//vertex index
	
	ifp>>graphSize;
	cout<<"Graph contains "<<graphSize<<" nodes"<<endl;
	degree = new VSize [graphSize];
	graph = new VertexID* [graphSize];
	long int avgDeg = 0;
	for(VSize i = 0; i<graphSize; i++)
	{
		if(i%50000 == 0) cout<<i<<" nodes have been read"<<endl;
		ULI curNode;
		VSize deg;
		
		ifp>>curNode>>deg;		
		avgDeg += deg;
		
		if(!vIndex.count(curNode))	//if new vertex, map it
		{
			cout<<"node id: "<<curNode<<", degree: "<<deg<<endl;
			vIndex[curNode] = count;
			index[count] = curNode;
			count++;
		}
		degree[vIndex[curNode]] = deg;
		graph[vIndex[curNode]] = new VertexID[deg];
		for(VSize k = 0; k<deg; k++)
		{
			ULI neiNode;
			Edge wei;
			float tmp;
			ifp>>neiNode>>wei>>tmp;	
			
			if(!vIndex.count(neiNode))
			{
				cout<<"node id: "<<neiNode<<", wei: "<<wei<<", tmp: "<<tmp<<endl;
				vIndex[neiNode] = count;
				index[count] = neiNode;
				count++;
			}
//			cout<<"\t"<<neiNode<<"\t"<<vIndex[neiNode]<<endl;
			graph[vIndex[curNode]][k] = vIndex[neiNode];
		}
	}
	cout<<"Total # of edges is "<<avgDeg<<endl;
	cout<<"Mean degree is "<<avgDeg/graphSize<<endl;
	ifp.close();
	cout<<"Graph reading success"<<endl;
}
void Graph::FreeGraph()
{
	FreeAll(graph, graphSize);
	FreeMem(degree);
}

